﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Text;
using Warensoft.DataService.DBHelpers;
using System.Reflection;
using Warensoft.Unity.Communication.Client.DataClient;
using Warensoft.Unity.Communication.Client.Models;

namespace Warensoft.DataService
{
    public abstract class DBHelper
    {
        private DataSet typedDataSet;
        private Assembly adaptersAssembly;
        public static DBHelper Create(DatabaseType type,DataSet typedDataSet)
        {
            var result= new SqlDBHelper();
            result.typedDataSet = typedDataSet;
            result.InitTableAdapters();
            return result;
        }
        public void InitTableAdapters()
        {
            this.adaptersAssembly = this.typedDataSet.GetType().Assembly;
        }
        public  ResultInfo ExecuteNonQuery(string connectionString, string commandText, Dictionary<string,object> parameters)
        {
            ResultInfo result = new ResultInfo();
            using (var con=this.CreateConnection ())
            {
                try
                {
                    con.ConnectionString = connectionString;
                    var cmd = con.CreateCommand();
                    cmd.CommandText = commandText;
                    if (parameters != null)
                    {
                        foreach (var parameter in parameters)
                        {
                            this.AddParameter(cmd, parameter.Key, parameter.Value);
                        }
                    }
                    result.OperationDone = true;
                }
                catch (Exception ex)
                {
                    result.OperationDone = false;
                    result.Message = ex.Message;
                }
            }
            return result;
        }
        public ResultInfo CreateDataSet(string connectionString, string commandText, Dictionary<string, object> parameters)
        {
            ResultInfo result = new ResultInfo();
            using (var con=this.CreateConnection ())
            {
                try
                {
                    con.ConnectionString = connectionString;
                    var cmd = con.CreateCommand();
                    cmd.CommandText = commandText;
                    if (parameters != null)
                    {
                        foreach (var parameter in parameters)
                        {
                            this.AddParameter(cmd, parameter.Key, parameter.Value);
                        }
                    }
                    var adpt = this.CreateDataAdapter();
                    adpt.SelectCommand = cmd;
                    DataSet ds = new DataSet();
                    adpt.Fill(ds);
                    result.OperationDone = true;
                    result.AdditionalData = ds;
                }
                catch (Exception ex)
                {
                    result.OperationDone = false;
                    result.Message = ex.Message;
                }
            }
            return result;
        }
        public DataSet GetSchema(string connectionString, string commandText)
        {
            DataSet ds = new DataSet ();
            using (var con = this.CreateConnection())
            {
               
                    con.ConnectionString = connectionString;
                    var cmd = con.CreateCommand();
                    cmd.CommandText = commandText;
                   
                    var adpt = this.CreateDataAdapter();
                    adpt.SelectCommand = cmd;
                   
                    adpt.FillSchema(ds, SchemaType.Source);
              
            }
            return ds;
        }
        //public ResultInfo BatchUpdate(string connectionString,List<DataEntity> entities)
        //{
        //    ResultInfo result = new ResultInfo();
        //    try
        //    {
        //        foreach (DataTable table in dsModified.Tables)
        //        {
        //            using (var con = this.CreateConnection())
        //            {
        //                con.ConnectionString = connectionString;
        //                var cmd = con.CreateCommand();
        //                cmd.CommandText = string.Format("select * from {0} ", table.TableName);
        //                var adpt = this.CreateDataAdapter();
        //                adpt.SelectCommand = cmd;
        //                var builder = this.CreateCommandBuilder();
        //                builder.DataAdapter = adpt;
        //                builder.ConflictOption = ConflictOption.OverwriteChanges;
        //                adpt.InsertCommand = builder.GetInsertCommand();
        //                adpt.DeleteCommand = builder.GetDeleteCommand();
        //                adpt.UpdateCommand = builder.GetUpdateCommand(true);
        //                con.Open();
        //                foreach (DataRow row in table .Rows )
        //                {
                            
        //                    foreach (DataColumn col in table.Columns )
        //                    {
        //                        adpt.UpdateCommand.Parameters["@" + col.ColumnName].Value = row[col.ColumnName];
        //                    }

        //                    adpt.UpdateCommand.ExecuteNonQuery();
        //                }
        //            }
        //        }
        //        result.OperationDone = true;
        //    }
        //    catch (Exception ex)
        //    {
        //        result.OperationDone = false;
        //        result.Message = ex.Message;
        //    }
        //    finally
        //    {
                
        //    }
        //    return result;
        //}
        public abstract DbConnection CreateConnection();
        public abstract DbDataAdapter CreateDataAdapter();
        public abstract DbCommandBuilder CreateCommandBuilder();
        public abstract DbParameter CreateParameter();
        public abstract void AddParameter(DbCommand cmd, string key, object value);

        
    }
}
